import time
from valkka.core import *
from valkka.api2 import ShmemRGBClient

#</hide>
"""<rtf>
The filtergraph, once again:

::


  (LiveThread:livethread) -------------------------------------+  main branch, streaming
                                                               |   
  {ForkFrameFilter: fork_filter} <----(AVThread:avthread) << --+  main branch, decoding
                 |
        branch 1 +->> (OpenGLThread:glthread)
                 |
        branch 2 +--> {IntervalFrameFilter: interval_filter} --> {SwScaleFrameFilter: sws_filter} --> {RGBSharedMemFrameFilter: shmem_filter}

<rtf>"""
# define yuv=>rgb interpolation interval
image_interval=1000  # YUV => RGB interpolation to the small size is done each 1000 milliseconds and passed on to the shmem ringbuffer

# define rgb image dimensions
width  =1920//4
height =1080//4

"""<rtf>
RGBSharedMemFrameFilter needs unique name and the size of the shared memory ring-buffer:
<rtf>"""
# posix shared memory
shmem_name    ="lesson_4"      # This identifies posix shared memory - must be unique
shmem_buffers =10              # Size of the shmem ringbuffer

"""<rtf>
Next, we construct the filterchain as usual, from end-to-beginning:
<rtf>"""
# branch 1
glthread        =OpenGLThread("glthread")
gl_in_filter    =glthread.getFrameFilter()
                                        
# branch 2
shmem_filter    =RGBShmemFrameFilter(shmem_name, shmem_buffers, width, height)
# shmem_filter    =BriefInfoFrameFilter("shmem") # a nice way for debugging to see of you are actually getting any frames here ..
sws_filter      =SwScaleFrameFilter("sws_filter", width, height, shmem_filter)
interval_filter =TimeIntervalFrameFilter("interval_filter", image_interval, sws_filter)

# fork
fork_filter     =ForkFrameFilter("fork_filter", gl_in_filter, interval_filter)

# main branch
avthread        =AVThread("avthread",fork_filter)
av_in_filter    =avthread.getFrameFilter()
livethread      =LiveThread("livethread")

"""<rtf>
Define connection to camera: frames from the IP camera are written to live_out_filter and tagged with slot number 1:
<rtf>"""
# ctx =LiveConnectionContext(LiveConnectionType_rtsp, "rtsp://admin:nordic12345@192.168.1.41", 1, av_in_filter)
ctx =LiveConnectionContext(LiveConnectionType_rtsp, "rtsp://admin:123456@192.168.0.134", 1, av_in_filter)
"""<rtf>
Start threads:
<rtf>"""
glthread.startCall()
avthread.startCall()
livethread.startCall()

# start decoding
avthread.decodingOnCall()

livethread.registerStreamCall(ctx)

# create an X-window
window_id =glthread.createWindow()
glthread.newRenderGroupCall(window_id)

# maps stream with slot 1 to window "window_id"
context_id=glthread.newRenderContextCall(1,window_id,0)

"""<rtf>
Ok, the server is alive and running.  Let's do the client part for receiving frames.
<rtf>"""
client = ShmemRGBClient(
    name=shmem_name,
    n_ringbuffer=shmem_buffers,
    width=width,
    height=height,
    mstimeout=1000,        # client timeouts if nothing has been received in 1000 milliseconds
    verbose=False
)

"""<rtf>
The client is ready to go.  Before starting to receive frames, start playing the RTSP camera
<rtf>"""
livethread.playStreamCall(ctx)

"""<rtf>
Read 10 frames & exit
<rtf>"""
print("client starting")
cc = 0
while True:
    index, meta = client.pullFrame()
    if (index == None):
        print("timeout")
    else:
        data = client.shmem_list[index][0:meta.size]
        data = data.reshape((meta.height, meta.width, 3))
        print("got data: ", data.shape)
        cc += 1
    if cc >= 10:
        break

print("stopping..")

"""<rtf>
Clear the server
<rtf>"""
glthread.delRenderContextCall(context_id)
glthread.delRenderGroupCall(window_id)

# stop decoding
avthread.decodingOffCall()

# stop threads
livethread.stopCall()
avthread.stopCall()
glthread.stopCall()

time.sleep(1)

print("bye")
